package com.eric.config;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Range;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: eric
 * @create: 2022-09-08 10:50
 * 混合分片策略，分片键record_time,record_date，支持区间查询，精确查询
 * 最好不要同时使用两个字段作为筛选条件，应该也不存在这种情况
 * 就算使用两个字段作为查询的时候，也是以create_time为准
 */
public class AttendanceComplexTableAlgorithm implements ComplexKeysShardingAlgorithm<Date> {
    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, ComplexKeysShardingValue<Date> shardingValue) {
        String logicTableName = shardingValue.getLogicTableName();
        Map<String, Range<Date>> columnNameAndRangeValuesMap = shardingValue.getColumnNameAndRangeValuesMap();
        //处理区间值
        if (CollUtil.isNotEmpty(columnNameAndRangeValuesMap)) {
            Range<Date> recordTime = columnNameAndRangeValuesMap.get("record_time");
            Range<Date> recordDate = columnNameAndRangeValuesMap.get("record_date");
            Date start;
            Date end;
            if (Objects.nonNull(recordTime)) {
                start = recordTime.lowerEndpoint();
                //没有上限的时候取明天的0点
                end = recordTime.hasUpperBound() ? recordTime.upperEndpoint() : DateUtil.beginOfDay(DateUtil.tomorrow());
            } else {
                start = recordDate.lowerEndpoint();
                //没有上限的时候取明天的0点
                end = recordDate.hasUpperBound() ? recordDate.upperEndpoint() : DateUtil.beginOfDay(DateUtil.tomorrow());
            }
            //计算间隔
            List<DateTime> dateTimes = DateUtil.rangeToList(start, end, DateField.DAY_OF_MONTH);
            return dateTimes.stream().map(date -> logicTableName + "_" + DateUtil.format(date, "yyyy_M")).collect(Collectors.toSet());
        }
        //处理精确值
        Map<String, Collection<Date>> columnNameAndShardingValuesMap = shardingValue.getColumnNameAndShardingValuesMap();
        if (CollUtil.isNotEmpty(columnNameAndShardingValuesMap)) {
            Collection<Date> recordTime = columnNameAndShardingValuesMap.get("record_time");
            Collection<Date> recordDate = columnNameAndShardingValuesMap.get("record_date");
            if (CollUtil.isNotEmpty(recordTime)) {
                return recordTime.stream().map(date -> logicTableName + "_" + DateUtil.format(date, "yyyy_M")).collect(Collectors.toSet());
            } else {
                return recordDate.stream().map(date -> logicTableName + "_" + DateUtil.format(date, "yyyy_M")).collect(Collectors.toSet());
            }
        }
        return null;
    }

//    @Override
//    public void init() {
//
//    }
//
//    @Override
//    public String getType() {
//        return null;
//    }
//
//    @Override
//    public Properties getProps() {
//        return null;
//    }
//
//    @Override
//    public void setProps(Properties properties) {
//
//    }
}
